#include "./Shape.h"
#ifndef HEAD_H
#include "../head.h"
#endif

/******************************************
 *        SinglePartShape 的实现           *
 * ****************************************/

SinglePartShape::SinglePartShape(ShapeType shape_type, ColorType color_type)
    : shape_type(shape_type), color_type(color_type) {}

void SinglePartShape::beColored(ColorType color) { this->color_type = color; }

bool SinglePartShape::isNone()
{
    return this->shape_type == ShapeType::NONE;
}

bool SinglePartShape::operator==(const SinglePartShape &other)
{
    return this->color_type == other.color_type && this->shape_type == other.shape_type;
}

bool SinglePartShape::operator!=(const SinglePartShape &other)
{
    return !(*this == other);
}

SinglePartShape::~SinglePartShape(){}

// SinglePartShape::~SinglePartShape() {} 暂时不需要自定义

/********************************************
 *        SingleLevelShape 的实现           *
 * *****************************************/

/**
 *          构造和析构函数
 */

SingleLevelShape::SingleLevelShape() {
    for(int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i){
        level_shape.push_back(new SinglePartShape());
    }
}

SingleLevelShape::SingleLevelShape(ShapeType shape_type, ColorType color_type)
{
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
        this->level_shape.push_back(new SinglePartShape(shape_type, color_type));
}

SingleLevelShape::SingleLevelShape(const SingleLevelShape &other)
{
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
        this->level_shape.push_back
            (new SinglePartShape(other.level_shape[i]->shape_type, other.level_shape[i]->color_type));
}

SingleLevelShape::SingleLevelShape(const std::string &hash_id)
{
    this->hash_id = hash_id;
    if (hash_id.size() != 2 * shape::PARTS_NUM_OF_EACH_LEVEL)
    {
        std::cerr<<("the string is not a standard level shape!");
    }
    this->deserialization();
}

SingleLevelShape::SingleLevelShape(const std::initializer_list<SPS *> &t_arr)
{
    if (t_arr.size() != shape::PARTS_NUM_OF_EACH_LEVEL)
    {
        std::cerr <<("You list's length must be shape::PARTS_NUM_OF_EACH_LEVEL");
    }
    SPS *const *it = t_arr.begin();
    for (;it != t_arr.end(); ++it)
    {this->level_shape.push_back(*(it));}
}

void SingleLevelShape::clear()
{
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
    {
        if (this->level_shape[i])
        {
            delete this->level_shape[i];
            this->level_shape[i] = null;
        }
    }
}

SingleLevelShape::~SingleLevelShape()
{
    SingleLevelShape::clear();
}

/**
 *          序列化和反序列化函数
 *          基本特征，是否为空
 */

std::string SingleLevelShape::serialization()
{
    if (this->hash_id.size())
    {
        return this->hash_id;
    }
    std::string single_string;
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
    {
        SinglePartShape *sps = this->level_shape[i];
        single_string += (char)sps->shape_type;
        if (sps->isNone())
        {
            single_string += (char)ColorType::Color_NONE;
        }
        else
        {
            single_string += (char)sps->color_type;
        }
    }
    return this->hash_id = single_string;
}

void SingleLevelShape::deserialization()
{
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
    {
        this->level_shape.push_back(new SinglePartShape((ShapeType)hash_id[i], (ColorType)hash_id[i + 1]));
    }
}

bool SingleLevelShape::isLeftNone()
{
    return this->level_shape[ShapePosition::Shape_LEFT_DOWN]->isNone() && this->level_shape[ShapePosition::Shape_LEFT_UP]->isNone();
}

bool SingleLevelShape::isRightNone()
{
    return this->level_shape[ShapePosition::Shape_RIGHT_DOWN]->isNone() && this->level_shape[ShapePosition::Shape_RIGHT_UP]->isNone();
}

bool SingleLevelShape::isNone()
{
    return this->isLeftNone() && this->isRightNone();
}

/**
 *         功能类函数：染色，切割，转向，堆叠
 */

void SingleLevelShape::beColored(ColorType color)
{
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
    {
        if (this->level_shape[i])
            this->level_shape[i]->beColored(color);
    }
}

std::pair<SLS *, SLS *> SingleLevelShape::beCrop()
{
    return {new SLS({new SPS(*this->level_shape[ShapePosition::Shape_LEFT_DOWN]),
                     new SPS(*this->level_shape[ShapePosition::Shape_LEFT_UP]),
                     new SPS(),
                     new SPS()}),
            new SLS({
                new SPS(),
                new SPS(),
                new SPS(*this->level_shape[ShapePosition::Shape_RIGHT_UP]),
                new SPS(*this->level_shape[ShapePosition::Shape_RIGHT_DOWN]),
            })};
}

void SingleLevelShape::turnDirection(bool is_clockwise)
{
    SinglePartShape *temp = this->level_shape[Shape_LEFT_DOWN];
    if (is_clockwise)
    {
        this->level_shape[Shape_LEFT_DOWN] = this->level_shape[Shape_RIGHT_DOWN];
        this->level_shape[Shape_RIGHT_DOWN] = this->level_shape[Shape_RIGHT_UP];
        this->level_shape[Shape_RIGHT_UP] = this->level_shape[Shape_LEFT_UP];
        this->level_shape[Shape_LEFT_UP] = temp;
    }
    else
    {
        this->level_shape[Shape_LEFT_DOWN] = this->level_shape[Shape_LEFT_UP];
        this->level_shape[Shape_LEFT_UP] = this->level_shape[Shape_RIGHT_UP];
        this->level_shape[Shape_RIGHT_UP] = this->level_shape[Shape_RIGHT_DOWN];
        this->level_shape[Shape_RIGHT_DOWN] = temp;
    }
    return;
}

/**
 *          重载运算符函数
 */

bool SingleLevelShape::operator==(const SingleLevelShape &other)
{
    for (int i = 0; i < shape::PARTS_NUM_OF_EACH_LEVEL; ++i)
    {
        if (*(this->level_shape[i]) != *(other.level_shape[i]))
            return false;
    }
    return true;
}

bool SingleLevelShape::operator!=(const SingleLevelShape &other)
{
    return !(*this == other);
}

/********************************************
 *        ShapeDefine 的实现                 *
 * *****************************************/

/**
 *          构造和析构函数
 */

ShapeDefine::ShapeDefine()
    : CargoDefine(CargoType::SHAPE), total_shapes(shape::MAX_LEVEL, null)
{
}

ShapeDefine::ShapeDefine(ShapeType shape_type, ColorType color_type)
    : ShapeDefine()
{
    this->total_shapes[0] = new SLS(shape_type, color_type);
    for (int i = 1; i < shape::MAX_LEVEL; ++i)
    {
        this->total_shapes[i] = new SLS();
    }
}

ShapeDefine::ShapeDefine(const ShapeDefine &other)
    : ShapeDefine()
{
    for (int i = 0; i < shape::MAX_LEVEL; ++i)
    {
        SingleLevelShape *level_shape = other.total_shapes[i];
        this->total_shapes[i] = new SingleLevelShape(*level_shape);
    }
}

ShapeDefine::ShapeDefine(const std::string &hash_id)
    : ShapeDefine()
{
    if (hash_id.size() != (1 + 2 * shape::PARTS_NUM_OF_EACH_LEVEL) * shape::MAX_LEVEL - 1)
    {
        std::cerr<<("the string is not a standard shape!");
    }
    this->hash_id = hash_id;
    this->deserialization();
}

ShapeDefine::ShapeDefine(const std::initializer_list<SLS *> &t_arr)
    : ShapeDefine()
{
    if (t_arr.size() > shape::MAX_LEVEL)
    {
        std::cerr << ("You list's length must less than shape::MAX_LEVEL");
    }
    SLS *const *it = t_arr.begin();
    int i = 0;
    for (; it != t_arr.end(); ++i, it++)
    {
        this->total_shapes[i] = *(it);
    }
    for (; i < shape::MAX_LEVEL; ++i)
    {
        this->total_shapes[i] = new SLS();
    }
}

void ShapeDefine::clear()
{
    for (auto &single_level_shape : total_shapes)
    {
        if (single_level_shape)
        {
            delete single_level_shape;
            single_level_shape = null;
        }
    }
}

ShapeDefine::~ShapeDefine()
{
    ShapeDefine::clear();
}

/**
 *      序列化和反序列化
 *      判断整体是否为空
 */

/// @details 这里约定
// 每层有 2*PARTS_NUM_OF_EACH_LEVEL 个字符
// 分别为 形状+颜色，每层使用','隔开
// 从前到后的顺序为 ShapePosition 的枚举顺序
//     Shape_LEFT_DOWN,               // 左下
//     Shape_LEFT_UP,                 // 左上
//     Shape_RIGHT_UP,                // 右上
//     Shape_RIGHT_DOWN,             // 右下
// 如："n@cAcAcA0n@n@n@n@" 表示两层,如果形状为n就为空,空的块只能是无颜色
// 第一层
std::string ShapeDefine::serialization()
{
    if (this->hash_id.size())
    {
        return this->hash_id;
    }
    std::string serialized_string;
    for (int i = 0; i < shape::MAX_LEVEL; ++i)
    {
        serialized_string += (this->total_shapes[i]->serialization() + shape::shape_split_char);
    }
    serialized_string.pop_back();
    return this->hash_id = serialized_string;
}

void ShapeDefine::deserialization()
{
    std::string hs;
    for (int i = 0; i < shape::MAX_LEVEL; ++i)
    {
        hs = hash_id.substr(i * (2*shape::PARTS_NUM_OF_EACH_LEVEL + 1), 2*shape::PARTS_NUM_OF_EACH_LEVEL);
        this->total_shapes[i] = new SingleLevelShape(hs);
    }
}

bool ShapeDefine::isNone()
{
    return isLeftNone() && isRightNone();
}

bool ShapeDefine::isLeftNone(){
    for (auto level_shape : this->total_shapes)
    {
        if (!level_shape->isLeftNone())
        {
            return false;
        }
    }
    return true;
}

bool ShapeDefine::isRightNone(){
    for (auto level_shape : this->total_shapes)
    {
        if (!level_shape->isRightNone())
        {
            return false;
        }
    }
    return true;
}

/**
 *      功能类函数：染色，裁剪，堆叠，旋转
 */

// ShapeDefine *ShapeDefine::stackOther(ShapeDefine &other);

ShapeDefine *ShapeDefine::beColored(ColorType color)
{
    ShapeDefine *copy = new ShapeDefine(*this);
    for (auto &level_shape : copy->total_shapes)
    {
        if (level_shape->isNone())
            continue;
        else
            level_shape->beColored(color);
    }
    return copy;
}

std::pair<ShapeDefine *, ShapeDefine *> ShapeDefine::beCropped()
{
    std::pair<ShapeDefine *, ShapeDefine *> pair_shape_cargos{
        new ShapeDefine({null}),
        new ShapeDefine({null})};
    for (int i = 0; i < shape::MAX_LEVEL; ++i)
    {
        SingleLevelShape *level_shape = this->total_shapes[i];
        std::pair<SLS *, SLS *> pair_shape = level_shape->beCrop();
        pair_shape_cargos.first->total_shapes[i] = pair_shape.first;
        pair_shape_cargos.second->total_shapes[i] = pair_shape.second;
    }
    return pair_shape_cargos;
}

ShapeDefine *ShapeDefine::turnDirection(bool is_clockwise)
{
    ShapeDefine *copy = new ShapeDefine(*this);
    for (auto &level_shape : copy->total_shapes)
    {
        if (level_shape->isNone())
            continue;
        else
            level_shape->turnDirection(is_clockwise);
    }
    return copy;
}

ShapeDefine *ShapeDefine::stackOther(ShapeDefine &other){
    // std::cerr<<("stackOther should not be called!");
    return new ShapeDefine(*this);
}

/********************************************
 *        ShapeCargo 的实现                 *
 * *****************************************/
ShapeCargo::ShapeCargo() : Cargo() {}
ShapeCargo::ShapeCargo(ShapeDefine *define) : Cargo(define) { ; }
ShapeCargo::~ShapeCargo(){}
bool ShapeCargo::operator==(const ShapeCargo &other)
{
    return this->define == other.define; // why? 因为define只有一个
}

/********************************************
 *        测试代码                           *
 * *****************************************/

#if IS_TEST > 0
int main()
{
}
#endif
